#ifndef NANE_ISCRIPTSYSTEM_H
#   define NANE_ISCRIPTSYSTEM_H

#   include "nane/core/types.h"
#   include "nane/core/enum.h"
#   include "nane/core/ISubSystem.h"

namespace nane
{
    struct IInput;
    struct IOutput;
    
    struct IScriptFunction
    {
        virtual bool Invoke( IInput* _args, IOutput* _results ) = 0;
    };

    struct IScriptObject
        : public IScriptFunction
    {
        virtual const char* ToString() = 0;
    };
    
    union TScriptValue
    {
        int            i;
        bool           b;
        float          f;
        const char*    s;
        IScriptObject* o;
    };

    struct EScriptValueType
        : public Enum<EScriptValueType>
    {
        enum domain
        {
            Unknown = 0,
            Integer,
            Boolean,
            Float,
            String,
            Object,

            _max
        };
        
        NANE_ENUM( EScriptValueType, Enum );
    };

    struct IScriptModule
        : public IScriptObject
    {
        //
        // imports script object from script module
        // -
        // precond:
        //   (none)
        // params:
        //   _objectName - non-null valid null-terminated string representing name of object to import
        // result:
        //   returns non-null IScriptObject interface pointer representing imported object or null on failure
        //
        virtual IScriptObject* ImportObject( const char* _objectName ) = 0;
        
        //
        // exports c-function to script module
        // -
        // precond:
        //   (none)
        // params:
        //   _className - null-terminated string representing scope of function or null if function is in global scope
        //   _functionName - non-null valid null-terminated string representing name of function in script module
        //   _cfunction - non-null valid IScriptFunction interface pointer representing c-function
        // result:
        //   returns non-null IScriptObject interface pointer if function was successfully exported, otherwise - null
        //
        virtual IScriptObject* ExportFunction( const char* _className, const char* _functionName, IScriptFunction* _cfunction ) = 0;
        
        //
        // releases script object
        // -
        // precond:
        //   (none)
        // params:
        //   _object - non-null valid IScriptObject pointer returned from 'ImportObject/ExportFunction'
        // result:
        //   all resources assigned with _object interface are released
        //              
        virtual void ReleaseObject( IScriptObject* _object ) = 0;
        
    };

    struct IScriptSystem
        : public ISubSystem
    {
        //virtual IScriptModule* createModule( const char* _moduleName ) = 0;
        
        //
        // creates script module from byte stream
        // -
        // precond:
        //   ScriptSystem must be initialized
        // params:
        //   _moduleName - non-null valid null-terminated string, just for more informative logging
        //   _input - non-null valid byte stream interface to load from
        // result:
        //   returns non-null IScriptModule interface pointer if module was successfully created and loaded, otherwise - null
        //   non-null IScriptModule pointer must be released with 'ReleaseModule' before SubSystem shutdown
        //        
        virtual IScriptModule* LoadModule( const char* _moduleName, IInput* _input ) = 0;
        
        //
        // executes script module
        // -
        // precond:
        //   ScriptSystem must be initialized
        // params:
        //   _module - non-null valid IScriptModule pointer returned from 'loadModule'
        // result:
        //   returns true if script module was successfully executed, otherwise - false
        //        
        virtual bool RunModule( IScriptModule* _module ) = 0;
        
        //
        // releases previously created script module
        // -
        // precond:
        //   ScriptSystem must be initialized
        // params:
        //   _module - non-null valid IScriptModule pointer returned by 'LoadModule'
        // result:
        //   all resources assigned with _module are released
        //        
        virtual void ReleaseModule( IScriptModule* _module ) = 0;
    };

} // namespace nane

#endif	// NANE_ISCRIPTSYSTEM_H
